//
//  BBButton.m
//  BattleFrontierV3
//
//  Created by Eric on 12/24/11.
//  Copyright (c) 2011 __MyCompanyName__. All rights reserved.
//

#import "BBButton.h"
#import "BBUtil.h"

@implementation BBButton
@synthesize touchMode;
@synthesize pack;
@synthesize isEnabled;

+(id)button:(NSString*)normal selected:(NSString*)selected disabled:(NSString*)disabled pack:(BBPackAction*)pack priority:(NSInteger)priority{
    BBButton* btn = [[self class] node];
    [btn initWithFrameName:normal selected:selected disabled:disabled priority:priority];
    btn.pack = pack;
    return btn;
}
+(id)button:(NSString*)normal selected:(NSString*)selected disabled:(NSString*)disabled pack:(BBPackAction*)pack{
    BBButton* btn = [[self class] node];
    [btn initWithFrameName:normal selected:selected disabled:disabled priority:kCCMenuTouchPriority];
    btn.pack = pack;
    return btn;
}
+(id)buttonFile:(NSString*)normal selected:(NSString*)selected disabled:(NSString*)disabled pack:(BBPackAction*)pack  priority:(NSInteger)priority{
    BBButton* btn = [[self class] node];
    [btn initWithFile:normal selected:selected disabled:disabled priority:priority];
    btn.pack = pack;
    return btn;
}
+(id)buttonFile:(NSString*)normal selected:(NSString*)selected disabled:(NSString*)disabled pack:(BBPackAction*)pack{
    BBButton* btn = [[[[self class] alloc] init] autorelease];
    [btn initWithFile:normal selected:selected disabled:disabled priority:kCCMenuTouchPriority];
    btn.pack = pack;
    return btn;
}
+(id)button:(NSString*)normal selected:(NSString*)selected disabled:(NSString*)disabled priority:(NSInteger)priority{
    BBButton* btn = [[self class] node];
    [btn initWithFrameName:normal selected:selected disabled:disabled priority:priority];
    return btn;
}
+(id)button:(NSString*)normal selected:(NSString*)selected disabled:(NSString*)disabled{
    BBButton* btn = [[self class] node];
    [btn initWithFrameName:normal selected:selected disabled:disabled priority:kCCMenuTouchPriority];
    return btn;
}
+(id)buttonFile:(NSString*)normal selected:(NSString*)selected disabled:(NSString*)disabled priority:(NSInteger)priority{
    BBButton* btn = [[self class] node];
    [btn initWithFile:normal selected:selected disabled:disabled priority:priority];
    return btn;
}
+(id)buttonFile:(NSString*)normal selected:(NSString*)selected disabled:(NSString*)disabled{
    BBButton* btn = [[[[self class] alloc] init] autorelease];
    [btn initWithFile:normal selected:selected disabled:disabled priority:kCCMenuTouchPriority];
    return btn;
}


-(void)initButton:(NSInteger)p{
    self.contentSize = normal.contentSize;
    self.anchorPoint = ccp(0.5f, 0.5f);
    normal.position = ccp(self.contentSize.width/2, self.contentSize.height/2);
    selected.position = ccp(self.contentSize.width/2, self.contentSize.height/2);
    isEnabled = YES;    
    
    [self addChild:normal z:1];
    
    if (selected) {
        [self addChild:selected z:2];
    }
    
    if (disabled) {
        disabled.position = ccp(self.contentSize.width/2, self.contentSize.height/2);
        [self addChild:disabled z:3];
        disabled.visible = NO;
    }
    state = kBBButtonStateWaiting;
    selected.visible = NO;
    
    touchMode = kBBButtonTouchModeUpInside;
    priority = p;
}
-(void)initWithFile:(NSString*)nor selected:(NSString*)sle disabled:(NSString*)dis priority:(NSInteger)p
{
    normal = [CCSprite spriteWithFile:nor];
    if (sle) {
        selected = [CCSprite spriteWithFile:sle];
    }else{
        selected = nil;
    }
    
    if (dis) {
        disabled = [CCSprite spriteWithFile:dis];
    }else{
        disabled = nil;
    }
    [self initButton:p];
}
-(void)initWithFrameName:(NSString*)nor selected:(NSString*)sle disabled:(NSString*)dis priority:(NSInteger)p
{
    normal = [CCSprite spriteWithSpriteFrameName:nor];
    if (sle) {
        selected = [CCSprite spriteWithSpriteFrameName:sle];
    }else{
        selected = nil;
    }
    
    if (dis) {
        disabled = [CCSprite spriteWithSpriteFrameName:dis];
    }else{
        disabled = nil;
    }
    [self initButton:p];
}

-(void)setIsEnabled:(BOOL)enb{
    isEnabled = enb;
    BOOL isSelected = state==kBBButtonStateTrackingTouch;
    normal.visible = !isSelected&&isEnabled;
    selected.visible = isSelected&&isEnabled;
    if (disabled) {
        disabled.visible = !isEnabled;
    }
}

#ifdef __IPHONE_OS_VERSION_MAX_ALLOWED
-(void)dealloc{
    //NSLog(@"BBButton:dealloc=%@", self);
    self.pack = nil;
    [super dealloc];
}

- (void)onEnter
{
	[[CCTouchDispatcher sharedDispatcher] addTargetedDelegate:self priority:priority swallowsTouches:YES];
	[super onEnter];
}

- (void) onExit
{
	normal.visible = YES;
    selected.visible = NO;
    state = kBBButtonStateWaiting;
    self.pack = nil;
    
	[[CCTouchDispatcher sharedDispatcher] removeDelegate:self];
	[super onExit];
}


-(void) registerWithTouchDispatcher
{
	[[CCTouchDispatcher sharedDispatcher] addTargetedDelegate:self priority:priority swallowsTouches:YES];
}



- (BOOL)containsTouchLocation:(UITouch *)touch rect:(CGRect)r
{
   // CGPoint touchLocation = [touch locationInView: [touch view]];
	//touchLocation = [[CCDirector sharedDirector] convertToGL: touchLocation];
    CGPoint local = [self convertTouchToNodeSpace:touch];
    
	return CGRectContainsPoint(r, ccp(local.x * self.scaleX, local.y * self.scaleY));
}

- (BOOL)containsTouchLocation:(UITouch *)touch
{
    CGRect r = [self boundingBox];
    r.origin = CGPointZero;
	return [self containsTouchLocation:touch rect:r];
}


-(BOOL) ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event
{
    @synchronized(self){
        if( state != kBBButtonStateWaiting || !visible_ ||!isEnabled)
            return NO;
        
        for( CCNode *c = self.parent; c != nil; c = c.parent )
            if( c.visible == NO )
                return NO;
        
        if ( ![self containsTouchLocation:touch]) 
            return NO;
        
        state = kBBButtonStateTrackingTouch;
        
        if (selected) {
            normal.visible = NO;
            selected.visible = YES;
        }
        if (touchMode == kBBButtonTouchModeDownInside) {
            [self.pack doAction];    
        }
    }
    return YES;
}

-(void) ccTouchEnded:(UITouch *)touch withEvent:(UIEvent *)event
{
    @synchronized(self){
        if (state == kBBButtonStateWaiting) {
            return;
        }
        
        if (selected) {
            normal.visible = YES;
            selected.visible = NO;
        }
        
        
        if (touchMode == kBBButtonTouchModeUpInside) {
            [self.pack doAction];
        }
        
        state = kBBButtonStateWaiting;
    }
}

-(void) ccTouchCancelled:(UITouch *)touch withEvent:(UIEvent *)event
{
    @synchronized(self){
        NSAssert(state == kBBButtonStateTrackingTouch, @"[BBButton ccTouchCancelled] -- invalid state");
        
        if (selected) {
            normal.visible = YES;
            selected.visible = NO;
        }
        
        state = kBBButtonStateWaiting;
    }
}

-(void) ccTouchMoved:(UITouch *)touch withEvent:(UIEvent *)event
{
    @synchronized(self){
        //NSAssert(state == kBBButtonStateTrackingTouch, @"[BBButton ccTouchMoved] -- invalid state");
        
        CGSize size = [[CCDirector sharedDirector] winSize];
        CGFloat extend = MIN(size.width, size.height) / 10;
        
        CGRect r = CGRectMake(position_.x - contentSize_.width*anchorPoint_.x - extend,
                              position_.y - contentSize_.height*anchorPoint_.y - extend,
                              contentSize_.width + extend * 2, contentSize_.height + extend * 2);	
        r.origin = CGPointZero;
        if ([self containsTouchLocation:touch rect:r]) return;
        
        if (selected) {
            normal.visible = YES;
            selected.visible = NO;
        }
        
        state = kBBButtonStateWaiting;
    }
}


#pragma mark Menu - Mouse

#elif defined(__MAC_OS_X_VERSION_MAX_ALLOWED)
-(void)dealloc{
    self.pack = nil;
    [keyCodes release];
    [keyMasks release];
    [super dealloc];
}
- (void)onEnter
{
	[[CCEventDispatcher sharedDispatcher] addMouseDelegate:self priority:priority];
    [[CCEventDispatcher sharedDispatcher] addKeyboardDelegate:self priority:priority];
	[super onEnter];
}

- (void) onExit
{
	normal.visible = YES;
    selected.visible = NO;
    state = kBBButtonStateWaiting;
    self.pack = nil;
    
	[[CCEventDispatcher sharedDispatcher] removeMouseDelegate:self];
    [[CCEventDispatcher sharedDispatcher] removeKeyboardDelegate:self];
	[super onExit];
}

-(void)addKeyCode:(unichar) keyCode{
    @synchronized(self){
        if (!keyCodes) {
            keyCodes = [[NSMutableArray alloc] init];
        }
    }
    [keyCodes addObject:[NSNumber numberWithInteger:keyCode]];
}
-(void)addKeyMask:(NSUInteger) keyMask{
    @synchronized(self){
        if (!keyMasks) {
            keyMasks = [[NSMutableArray alloc] init];
        }
    }
    [keyMasks addObject:[NSNumber numberWithInteger:keyMask]];
}

-(BOOL)containsTouchLocation:(NSEvent*)event rect:(CGRect)r{
    // CGPoint touchLocation = [touch locationInView: [touch view]];
	//touchLocation = [[CCDirector sharedDirector] convertToGL: touchLocation];
    CGPoint local = [(CCDirectorMac*)[CCDirector sharedDirector] convertEventToGL:event];
    local = [self convertToNodeSpace:local];
	return CGRectContainsPoint(r, ccp(local.x * self.scaleX, local.y * self.scaleY));
}

-(BOOL)containsTouchLocation:(NSEvent*)event{
    CGRect r;
    r.origin = CGPointZero;
    r.size = self.contentSize;
	return [self containsTouchLocation:event rect:r];
}


-(BOOL) ccMouseDown:(NSEvent *)event
{
    @synchronized(self){
        if( ! visible_ )
            return NO;
        
        if( state != kBBButtonStateWaiting || !visible_ ||!isEnabled)
            return NO;
        
        for( CCNode *c = self.parent; c != nil; c = c.parent )
            if( c.visible == NO )
                return NO;
        
        
        if ( ![self containsTouchLocation:event]) 
            return NO;
        
        state = kBBButtonStateTrackingTouch;
        
        if (selected) {
            normal.visible = NO;
            selected.visible = YES;
        }
        if (touchMode == kBBButtonTouchModeDownInside) {
            [self.pack doAction];    
        }
    }
    return YES;	
}

-(BOOL) ccMouseUp:(NSEvent *)event
{
    @synchronized(self){
        if( ! visible_ )
            return NO;
        
        if (state == kBBButtonStateWaiting) {
            return NO;
        }
        
        if (selected) {
            normal.visible = YES;
            selected.visible = NO;
        }
        
        if (touchMode == kBBButtonTouchModeUpInside) {
            [self.pack doAction];
        }
        state = kBBButtonStateWaiting;
    }
    return YES;
}


-(BOOL) ccMouseDragged:(NSEvent *)event
{
     @synchronized(self){
         if( ! visible_ )
             return NO;
         
         CGSize size = [[CCDirector sharedDirector] winSize];
         CGFloat extend = MIN(size.width, size.height) / 10;
         
         CGRect r = CGRectMake(position_.x - contentSize_.width*anchorPoint_.x - extend,
                               position_.y - contentSize_.height*anchorPoint_.y - extend,
                               contentSize_.width + extend * 2, contentSize_.height + extend * 2);	
         r.origin = CGPointZero;
         
         if ([self containsTouchLocation:event rect:r]) return NO;
         
         if (selected) {
             normal.visible = YES;
             selected.visible = NO;
         }
         
         state = kBBButtonStateWaiting;
         
     }
    return YES;
}

-(BOOL) ccKeyUp:(NSEvent*)event{
    @synchronized(self){
        if( ! visible_ )
            return NO;
        
        if (state == kBBButtonStateWaiting) {
            return NO;
        }
        
        NSString * character = [event characters];
        unichar keyCode = [character characterAtIndex: 0];
        
        for (NSNumber* num in keyCodes) {
            unichar registedKeyCode = [num charValue];
            if (keyCode == registedKeyCode) {            
                if (selected) {
                    normal.visible = YES;
                    selected.visible = NO;
                }
                
                if (touchMode == kBBButtonTouchModeUpInside) {
                    [self.pack doAction];
                }
                state = kBBButtonStateWaiting;
                return YES;
            }
        }
    }
    
    return NO;
}
-(BOOL) ccKeyDown:(NSEvent*)event{
    @synchronized(self){
        if( ! visible_ )
            return NO;
        
        if( state != kBBButtonStateWaiting || !visible_ ||!isEnabled)
            return NO;
        
        for( CCNode *c = self.parent; c != nil; c = c.parent )
            if( c.visible == NO )
                return NO;
        
        NSString * character = [event characters];
        unichar keyCode = [character characterAtIndex: 0];
        //NSLog(@"keycode=%d", keyCode);
        for (NSNumber* num in keyCodes) {
            unichar registedKeyCode = [num charValue];
            if (keyCode == registedKeyCode) {
                state = kBBButtonStateTrackingTouch;
                
                if (selected) {
                    normal.visible = NO;
                    selected.visible = YES;
                }
                if (touchMode == kBBButtonTouchModeDownInside) {
                    [self.pack doAction];    
                }
                return YES;	
            }
        }
    }
    
    return NO;
}

-(BOOL) ccFlagsChanged:(NSEvent*)event{
    @synchronized(self){
        if (state == kBBButtonStateWaiting) {
            NSUInteger flag = [event modifierFlags];
            for (NSNumber* num in keyMasks) {
                NSUInteger registedKeyMask = [num unsignedIntValue];
                if (flag & registedKeyMask) {
                    state = kBBButtonStateTrackingTouch;
                    normal.visible = NO;
                    selected.visible = YES;
                    if (touchMode == kBBButtonTouchModeDownInside) {
                        [self.pack doAction];    
                    }               
                    return YES;	
                }
            }
        }else if (state == kBBButtonStateTrackingTouch) {
            state = kBBButtonStateWaiting;
            normal.visible = YES;
            selected.visible = NO;                
            if (touchMode == kBBButtonTouchModeUpInside) {
                [self.pack doAction];
            }
            return YES;
        }
    }

    return NO;
}



#endif // Mac Mouse support
@end







@implementation BBCheckbox

-(BOOL)isChecked{
    return state == kBBButtonStateTrackingTouch;
}
-(void)checked:(BOOL)chk{
    if (chk) {
        state = kBBButtonStateTrackingTouch;
        if (selected) {
            normal.visible = NO;
            selected.visible = YES;
        }
    }else{
        state = kBBButtonStateWaiting;
        if (selected) {
            normal.visible = YES;
            selected.visible = NO;
        }
    }
}

#ifdef __IPHONE_OS_VERSION_MAX_ALLOWED
- (BOOL)ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event
{
    @synchronized(self){
        if(!visible_ || !isEnabled)
            return NO;
        
        for( CCNode *c = self.parent; c != nil; c = c.parent )
            if( c.visible == NO )
                return NO;
        
        if ( ![self containsTouchLocation:touch]) 
            return NO;
        
        if (state == kBBButtonStateWaiting) {
            state = kBBButtonStateTrackingTouch;
            
            if (selected) {
                normal.visible = NO;
                selected.visible = YES;
            }
        }else{
            state = kBBButtonStateWaiting;
            
            if (selected) {
                normal.visible = YES;
                selected.visible = NO;
            }
        }
        
        
        
        [self.pack doAction];
    }
	return YES;
}

- (void)ccTouchMoved:(UITouch *)touch withEvent:(UIEvent *)event
{
}

- (void)ccTouchEnded:(UITouch *)touch withEvent:(UIEvent *)event
{
    
}
#pragma mark Menu - Mouse
#elif defined(__MAC_OS_X_VERSION_MAX_ALLOWED)
-(BOOL) ccMouseDown:(NSEvent *)event
{
    @synchronized(self){
        if( ! visible_ )
            return NO;
        
        for( CCNode *c = self.parent; c != nil; c = c.parent )
            if( c.visible == NO )
                return NO;
        
        if ( ![self containsTouchLocation:event]) 
            return NO;
        
        if (state == kBBButtonStateWaiting) {
            state = kBBButtonStateTrackingTouch;
            
            if (selected) {
                normal.visible = NO;
                selected.visible = YES;
            }
        }else{
            state = kBBButtonStateWaiting;
            
            if (selected) {
                normal.visible = YES;
                selected.visible = NO;
            }
        }    
        
        [self.pack doAction];
    }
    return YES;	
}
-(BOOL) ccMouseDragged:(NSEvent *)event
{
	return NO;
}

-(BOOL) ccMouseUp:(NSEvent *)event
{
    return NO;
}
-(BOOL) ccKeyDown:(NSEvent*)event{
    @synchronized(self){
        if( ! visible_ )
            return NO;
        
        for( CCNode *c = self.parent; c != nil; c = c.parent )
            if( c.visible == NO )
                return NO;
        
        NSString * character = [event characters];
        unichar keyCode = [character characterAtIndex: 0];
        //NSLog(@"keycode=%d", keyCode);
        for (NSNumber* num in keyCodes) {
            unichar registedKeyCode = [num charValue];
            if (keyCode == registedKeyCode) {
                if (state == kBBButtonStateWaiting) {
                    state = kBBButtonStateTrackingTouch;
                    
                    if (selected) {
                        normal.visible = NO;
                        selected.visible = YES;
                    }
                }else{
                    state = kBBButtonStateWaiting;
                    
                    if (selected) {
                        normal.visible = YES;
                        selected.visible = NO;
                    }
                }    
                
                [self.pack doAction];
                return YES;
            }
        }
    }
    return NO;
}

-(BOOL) ccKeyUp:(NSEvent*)event{
    return NO;
}
-(BOOL) ccFlagsChanged:(NSEvent*)event{
    @synchronized(self){
        NSUInteger flag = [event modifierFlags];
        for (NSNumber* num in keyMasks) {
            NSUInteger registedKeyMask = [num unsignedIntValue];
            if (flag & registedKeyMask) {
                if (state == kBBButtonStateWaiting) {
                    state = kBBButtonStateTrackingTouch;
                    normal.visible = NO;
                    selected.visible = YES;
                }else{
                    state = kBBButtonStateWaiting;
                    
                    if (selected) {
                        normal.visible = YES;
                        selected.visible = NO;
                    }
                }
                [self.pack doAction]; 
                return YES;	
            }
        }
        return YES;
    }
    
    return NO;
}


#endif 
@end

